local skynet = require "skynet"
local msg_center = require "agents.msg_center"
local player_manager = require "agents.player_manager"
local watchdog_proxy = require "agents.watchdog_proxy"
local MessageType = require "common.message_type"
local proto_manager = require "common.proto_manager"
local msg_handler_helper = require "agents.msg_handler_helper"
local service_helper = require "common.service_helper"
local Player = require "agents.player"
local message_packet = require "common.message_packet"

local function onBeginMatchReq(fd,id,data)

    local req = msg_handler_helper.parseProtoMessage(fd,"MessageBeginMatchReq",data)
    if not req then
        return
    end

    local player = msg_handler_helper.checkGetPlayerByFd(fd)
    if not player then
        return
    end

    local resp = {
        result = proto_manager.errcode("ErrorCode_Failed")
    }

    repeat

        if player:isInMatch() then
            resp.result = proto_manager.errcode("ErrorCode_AlreadyInMatch")
            return
        end

        player:setState(Player.State.Match)

        local data = {
            open_id = player:getOpenID(),
        }
        service_helper.send2Match(MessageType.MessageId_BeginMatchReq,data)

        resp.result = proto_manager.ErrorCode_Successed

    until true

    if resp.result ~= proto_manager.ErrorCode_Successed then
        player:sendMessage("MessageId_BeginMatchResp","MessageBeginMatchResp",resp)
    end

end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_BeginMatchReq"),onBeginMatchReq)

local function onBeginMatchResp(data)
    local player = msg_handler_helper.checkGetPlayerByOpenID(data.open_id)
    if not player then
        return
    end
    if data.result ~= proto_manager.ErrorCode_Successed then
        player:setState(Player.State.None)
    end
    local resp = {
        result = data.result,
        match_id = data.match_id,
        players = data.players,
    }
    player:sendMessage("MessageId_BeginMatchResp","MessageBeginMatchResp",resp)
end
msg_center.setDefaultMessageHandler(MessageType.MessageId_BeginMatchResp,onBeginMatchResp)


local function onCancelMatchReq(fd,id,data)
    local req = msg_handler_helper.parseProtoMessage(fd,"MessageCancelMatchReq",data)
    if not req then
        return
    end

    local player = msg_handler_helper.checkGetPlayerByFd(fd)
    if not player then
        return
    end

    local resp = {
        result = proto_manager.errcode("ErrorCode_Failed"),
        match_id = req.match_id,
    }

    repeat

        if (not req.match_id) or (0 == req.match_id) then
            return
        end

        if not player:isInMatch() then
            resp.result = proto_manager.errcode("ErrorCode_MatchAlreadyCanceled")
            return
        end

        local data = {
            match_id = req.match_id,
            open_id = player:getOpenID(),
        }
        service_helper.send2Match(MessageType.MessageId_CancelMatchReq,data)

        resp.result = proto_manager.ErrorCode_Successed

    until true

    if resp.result ~= proto_manager.ErrorCode_Successed then
        player:sendMessage("MessageId_CancelMatchResp","MessageCancelMatchResp",resp)
    end
end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_CancelMatchReq"),onCancelMatchReq)

local function onCancelMatchResp(data)
    local player = msg_handler_helper.checkGetPlayerByOpenID(data.open_id)
    if not player then
        return
    end
    if proto_manager.ErrorCode_Successed == data.result then
        player:setState(Player.State.None)
    end
    local resp = {
        result = data.result,
        match_id = data.match_id,
    }
    player:sendMessage("MessageId_CancelMatchResp","MessageCancelMatchResp",resp)
end
msg_center.setDefaultMessageHandler(MessageType.MessageId_CancelMatchResp,onCancelMatchResp)


local function onFightReadyReq(fd,id,data)

    local req = msg_handler_helper.parseProtoMessage(fd,"MessageFightReadyReq",data)
    if not req then
        return
    end

    local player = msg_handler_helper.checkGetPlayerByFd(fd)
    if not player then
        return
    end

    local resp = {
        result = proto_manager.errcode("ErrorCode_Failed"),
        match_id = req.match_id,
        state = req.state,
    }

    repeat

        if (not req.match_id) or (0 == req.match_id) then
            break
        end

        if not player:isInMatch() then
            resp.result = proto_manager.errcode("ErrorCode_NotInMatch")
            break
        end

        local data = {
            match_id = req.match_id,
            open_id = player:getOpenID(),
            state = req.state,
        }
        service_helper.send2Match(MessageType.MessageId_FightReadyReq,data)

        resp.result = proto_manager.ErrorCode_Successed

    until true

    if resp.result ~= proto_manager.ErrorCode_Successed then
        player:sendMessage("MessageId_FightReadyResp","MessageFightReadyResp",resp)
    end
end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_FightReadyReq"),onFightReadyReq)

local function onFightReadyResp(data)
    local player = msg_handler_helper.checkGetPlayerByOpenID(data.open_id)
    if not player then
        return
    end
    local resp = {
        result = data.result,
        match_id = data.match_id,
        state = data.state,
    }
    player:sendMessage("MessageId_FightReadyResp","MessageFightReadyResp",resp)
end
msg_center.setDefaultMessageHandler(MessageType.MessageId_FightReadyResp,onFightReadyResp)

local function onEndGameReq(fd,id,data)

    local req = msg_handler_helper.parseProtoMessage(fd,"MessageEndGameReq",data)
    if not req then
        return
    end
    local player = msg_handler_helper.checkGetPlayerByFd(fd)
    if not player then
        return
    end

    local resp = {
        result = proto_manager.errcode("ErrorCode_Failed"),
        room_id = req.room_id,
        players = req.players,
    }

    repeat

        if (not req.room_id) or (0 == req.room_id) then
            break
        end

        if not player:isInMatch() then
            resp.result = proto_manager.errcode("ErrorCode_NotInMatch")
            break
        end

        local data = {
            room_id = req.room_id,
            open_id = player:getOpenID(),
            players = req.players,
        }
        service_helper.send2Match(MessageType.MessageId_EndGameReq,data)

        resp.result = proto_manager.ErrorCode_Successed

    until true

    if resp.result ~= proto_manager.ErrorCode_Successed then
        player:sendMessage("MessageId_EndGameResp","MessageEndGameResp",resp)
    end

end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_EndGameReq"),onEndGameReq)

local function onEndGameResp(data)
    local player = msg_handler_helper.checkGetPlayerByOpenID(data.open_id)
    if not player then
        return
    end
    if proto_manager.ErrorCode_Successed == data.result then
        player:setState(Player.State.None)
    end
    local resp = {
        result = data.result,
        room_id = data.room_id,
        players = data.players,
    }
    player:sendMessage("MessageId_EndGameResp","MessageEndGameResp",resp)
end
msg_center.setDefaultMessageHandler(MessageType.MessageId_EndGameResp,onEndGameResp)

local function onGameEndFailed(data)
    local player = msg_handler_helper.checkGetPlayerByOpenID(data.open_id)
    if not player then
        return
    end
    player:setState(Player.State.None)
    local resp = {
        result = data.result,
        room_id = data.room_id,
    }
    player:sendMessage("MessageId_NotifyGameEndFailed","MessageNotifyGameEndFailed",resp)
end
msg_center.setDefaultMessageHandler(MessageType.MessageId_NotifyGameEndFailed,onGameEndFailed)

local function onGetFramesReq(fd,id,data)

    local req = msg_handler_helper.parseProtoMessage(fd,"MessageGetFramesReq",data)
    if not req then
        return
    end
    local player = msg_handler_helper.checkGetPlayerByFd(fd)
    if not player then
        return
    end

    local resp = {
        result = proto_manager.errcode("ErrorCode_Failed"),
        room_id = req.room_id,
        frames = {},
    }

    repeat

        if (not req.room_id) or (0 == req.room_id) then
            break
        end

        if not player:isInMatch() then
            resp.result = proto_manager.errcode("ErrorCode_NotInMatch")
            break
        end

        local data = {
            room_id = req.room_id,
            open_id = player:getOpenID(),
        }
        service_helper.send2Race(MessageType.MessageId_GetFramesReq,data)

        resp.result = proto_manager.ErrorCode_Successed

    until true

    if resp.result ~= proto_manager.ErrorCode_Successed then
        player:sendMessage("MessageId_GetFramesResp","MessageGetFramesResp",resp)
    end

end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_GetFramesReq"),onGetFramesReq)